AVL 트리
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
AVL 트리는 높이 균형 성질을 만족하는 이진 탐색 트리이다. 모든 노드의 자식 노드 간 높이 차이가 최대 1인 특징을 가지며, 이로 인해 O(log n)의 검색 시간 복잡도를 보장한다. 균형 인자를 통해 트리의 균형을 유지하며, 삽입, 삭제 시 회전을 통해 트리를 재구성한다. AVL 트리는 집합 연산을 지원하며, 레드-블랙 트리에 비해 탐색 성능이 우수하지만, 삽입 및 삭제 성능은 상대적으로 낮다. 데이터베이스, 운영체제 등에서 효율적인 자료 구조로 활용된다.
더 읽어볼만한 페이지
- 탐색 트리 - AA 트리
AA 트리는 컴퓨터 과학의 자료 구조 중 하나이며, 학술 연구 및 특정 기술 분야에서 활용된다. - 탐색 트리 - 스플레이 트리
스플레이 트리는 스플레이 연산을 통해 자가 균형을 유지하며 최근 접근 노드의 빠른 접근을 가능하게 하는 이진 탐색 트리로, 분할 상환 분석 시 평균적으로 O(log n)의 시간 복잡도를 가진다. - 분할 상환 자료 구조 - 스플레이 트리
스플레이 트리는 스플레이 연산을 통해 자가 균형을 유지하며 최근 접근 노드의 빠른 접근을 가능하게 하는 이진 탐색 트리로, 분할 상환 분석 시 평균적으로 O(log n)의 시간 복잡도를 가진다. - 분할 상환 자료 구조 - 피보나치 힙
피보나치 힙은 최소 힙 속성을 가진 트리들의 집합으로, 각 노드의 차수를 특정 로그 값 이하로 유지하여 효율적인 삽입, 병합, 최소값 검색 연산을 지원하며, 다익스트라 알고리즘과 같은 그래프 알고리즘의 성능 향상에 활용된다.
AVL 트리 | |
---|---|
개요 | |
종류 | 자체 균형 이진 탐색 트리 |
고안자 | 게오르기 아델손-벨스키와 예브게니 란디스 |
고안 연도 | 1962년 |
성능 | |
평균 공간 복잡도 | O(n) |
평균 탐색 시간 복잡도 | O(log n) |
최악 탐색 시간 복잡도 | O(log n) |
평균 삽입 시간 복잡도 | O(log n) |
최악 삽입 시간 복잡도 | O(log n) |
평균 삭제 시간 복잡도 | O(log n) |
최악 삭제 시간 복잡도 | O(log n) |
2. 정의와 성질
AVL 트리는 각 노드에서 왼쪽 및 오른쪽 부분 트리의 높이 차이가 1 이하인 '높이 균형 성질'을 만족하는 이진 탐색 트리의 일종이다. 트리 의 모든 내부 노드 에 대하여 의 자식 노드들의 높이 차이가 최대 1일 때, 이진 탐색 트리 는 AVL 트리라고 한다.
높이 균형 성질로 인해 개의 원소를 갖는 AVL 트리의 높이는 이다. 이진 탐색 트리에서의 검색 시간 복잡도는 트리의 높이이므로 AVL 트리의 검색 시간은 임을 알 수 있다. 일반적인 이진 탐색 트리는 입력되는 데이터의 순서에 따라 트리의 구성이 달라지기 때문에 탐색 효율이 안정적이지 않다. 예를 들어, 데이터가 정렬된 상태로 순서대로 입력되면 트리는 선형 리스트와 등가적인 구조가 되므로, 탐색의 계산량은 최악의 이 된다. 하지만 AVL 트리는 항상 트리의 균형을 유지하여 탐색의 계산량이 항상 정도가 된다.
2. 1. 균형 인자 (Balance Factor)
이진 트리에서 노드 X의 ''균형 인자''는 다음과 같이 정의된다.[6]: (오른쪽 부분 트리의 높이) - (왼쪽 부분 트리의 높이)
이는 노드 X를 루트로 하는 두 자식 서브 트리의 높이 차이이다.
균형 인자가 0보다 작은 노드 X는 "왼쪽으로 치우침", 균형 인자가 0보다 큰 노드는 "오른쪽으로 치우침"이라고 하며, 균형 인자가 0인 노드는 때때로 단순히 "균형"이라고 부른다. 균형 인자는 이전 균형 인자와 높이의 변화를 앎으로써 최신 상태로 유지할 수 있으며, 절대 높이를 알 필요는 없다. AVL 균형 정보를 유지하기 위해 노드당 2비트면 충분하다.[7]
AVL 트리에서는 데이터를 삽입하거나 삭제할 때마다 모든 노드의 균형 인자를 확인한다. 균형 인자는 다음과 같이 각 노드의 좌우 부분 트리의 높이 차이로 정의한다 (좌우는 반대여도 된다).
: (균형 계수) = (왼쪽 부분 트리의 높이) - (오른쪽 부분 트리의 높이)
균형 계수는 삽입이나 삭제 등의 조작 시마다 다시 계산한다. 왼쪽 부분 트리가 더 높을수록 +1, 오른쪽 부분 트리가 더 높을수록 -1 하면 된다.
균형 계수가 2 이상 또는 -2 이하인 노드가 존재하면 트리의 재구성이 필요하다. 재구성 후에는 균형 계수를 갱신한다.
2. 2. 높이 (Height)
'''높이 균형 성질'''(height-balance property)에 의해 개의 원소를 갖는 AVL 트리의 높이는 이다. 이진 탐색 트리에서 검색 시간 복잡도는 트리의 높이이므로 AVL 트리의 검색 시간이 임을 알 수 있다.[7]개의 노드를 가진 AVL 트리의 높이 (최대 레벨 수로 계산)는 다음 구간에 있다.[6]
:
여기서 는 황금비이고, 이다. 이는 높이 인 AVL 트리가 최소 개의 노드를 포함하기 때문이며, 여기서 는 시드 값 을 갖는 피보나치 수열이다.
일반적인 이진 탐색 트리는 입력되는 데이터 순서에 따라 트리 구성이 달라져 탐색 효율이 안정적이지 않다. 예를 들어, 데이터가 정렬된 상태로 순서대로 입력되면 트리는 선형 리스트와 같은 구조가 되므로, 탐색의 계산량은 최악의 경우 이 된다. 트리가 완전 이진 트리이면 계산량은 최상의 경우 이 되지만, 완전 이진 트리가 아니더라도 트리 전체 높이가 더 작고 균형이 잡힌(평형) 상태라면 트리 성능은 충분히 발휘될 수 있다. AVL 트리는 "어떤 노드의 좌우 서브트리 높이 차도 1 이하"임을 평형 조건으로 하며, 이를 항상 만족하므로 탐색 계산량은 항상 정도가 된다.
3. 연산 (Operations)
AVL 트리의 읽기 전용 연산(탐색, 순회 등)은 일반적인 이진 탐색 트리와 동일하게 수행된다. 하지만 수정 연산(삽입, 삭제)의 경우, 트리의 균형이 깨질 수 있으므로 회전 연산을 통해 균형을 유지해야 한다.
AVL 트리에서는 데이터를 삽입하거나 삭제할 때마다 모든 노드의 균형 계수를 확인하여 트리의 균형 상태를 점검한다. 균형 계수는 (왼쪽 서브트리의 높이) - (오른쪽 서브트리의 높이)로 정의되며, 이 값이 2 이상 또는 -2 이하인 노드가 존재하면 트리의 재구성이 필요하다. 회전은 균형 계수가 2 이상 또는 -2 이하인 노드 중 가장 잎에 가까운 노드부터 수행한다. 회전 연산에 대한 자세한 내용은 트리 회전 문서를 참고하면 된다.
AVL 트리는 합집합, 교집합, 차집합과 같은 집합 연산을 지원한다.[13] 이러한 연산은 분할(Split)과 결합(Join)이라는 두 가지 보조 연산을 기반으로 효율적으로 구현될 수 있다.
- 결합(Join) 연산: 두 개의 AVL 트리 과 및 키 가 주어졌을 때, 과 의 모든 요소와 를 포함하는 하나의 트리를 반환한다. 단, 는 의 모든 키보다 크고 의 모든 키보다 작아야 한다.
- 분할(Split) 연산: AVL 트리를 특정 키 를 기준으로 작은 두 개의 트리로 나눈다. 하나는 보다 작은 키를, 다른 하나는 보다 큰 키를 갖는 트리이다.
이러한 보조 연산들을 사용하여 두 AVL 트리의 합집합, 교집합, 차집합을 구할 수 있으며, 재귀 호출이 서로 독립적이므로 병렬 처리가 가능하다.[13]
3. 1. 탐색 (Searching)
AVL 트리에서 특정 키를 검색하는 것은 균형 또는 불균형 이진 탐색 트리와 동일한 방식으로 수행할 수 있다.[8] 검색이 효과적으로 작동하려면 키 집합에 대한 전순서 (또는 적어도 전체 전순서)를 설정하는 비교 함수를 사용해야 한다.[9] 성공적인 검색에 필요한 비교 횟수는 높이에 의해 제한되며, 실패한 검색의 경우 높이에 매우 가깝기 때문에 둘 다 O(log n)에 해당한다.[10]일반적인 이진 탐색 트리는 입력되는 데이터의 순서에 따라 트리의 구성이 달라지기 때문에, 탐색 효율이 안정적이지 않다. 예를 들어, 데이터가 정렬된 상태로 순서대로 입력되면 트리는 선형 리스트와 등가적인 구조가 되므로, 탐색의 계산량은 최악의 경우 O(n)이 된다. 트리가 완전 이진 트리이면 계산량은 최상의 경우 O(log n)이 되지만, 완전 이진 트리가 아니더라도 트리 전체의 높이가 더 작고 균형이 잡힌 상태, 즉 평형 상태라면 트리의 성능은 충분히 발휘될 수 있다. AVL 트리는 "어떤 노드의 좌우 서브트리의 높이 차도 1 이하"임을 평형 조건으로 하며, 이를 항상 만족하므로, 탐색의 계산량은 항상 O(log n) 정도가 된다.
목표 값을 가진 노드를 트리에서 찾아내는 것이 탐색이다. AVL 트리의 탐색은 일반적인 이진 탐색 트리와 동일한 절차로, "왼쪽 자식의 값 ≤ 부모의 값 ≤ 오른쪽 자식의 값" 조건을 단서로 진행한다.
# 루트 노드에 주목한다.
# 주목하고 있는 노드가 존재하지 않으면, 트리에 목표 값을 가진 노드가 없으므로 처리를 종료한다.
# "주목하고 있는 노드의 값"과 "목표 값"을 비교한다.
## 값이 같으면 탐색 종료
## "목표 값 < 주목하고 있는 노드의 값"이면, 왼쪽 자식 노드를 새로운 주목 노드로 하여 위 과정부터 반복한다.
## "주목하고 있는 노드의 값 < 목표 값"이면, 오른쪽 자식 노드를 새로운 주목 노드로 하여 위 과정부터 반복한다.
3. 2. 순회 (Traversal)
AVL 트리의 순회는 읽기 전용 연산으로, 다른 모든 이진 트리와 동일한 방식으로 작동한다. 트리의 n개 노드를 모두 탐색하면 각 링크를 정확히 두 번 방문한다. 한 번은 해당 노드를 루트로 하는 서브트리에 진입하기 위해 아래로 방문하고, 다른 한 번은 해당 노드의 서브트리를 탐색한 후 해당 노드를 떠나기 위해 위로 방문한다.AVL 트리에서 노드를 찾으면 "다음" 또는 "이전" 노드에 상각된 상수 시간에 접근할 수 있다.[12] 이러한 "인접" 노드를 탐색하는 일부 사례에서는 최대 log(n)개의 링크를 거쳐야 한다 (특히 루트의 왼쪽 서브트리의 가장 오른쪽 리프에서 루트로 이동하거나 루트에서 루트의 오른쪽 서브트리의 가장 왼쪽 리프로 이동할 때. 그림 1의 AVL 트리에서 노드 P에서 오른쪽으로 두 번째 노드 Q로 이동하는 데 3단계가 소요된다). 모든 트리에는 n-1개의 링크가 있으므로 상각 비용은 2×(n-1)/n, 즉 약 2이다.
3. 3. 삽입 (Insert)
AVL 트리에 새로운 노드를 삽입하는 과정은 다음과 같다.1. 이진 탐색 트리에서처럼 새 노드를 삽입한다. 빈 트리라면 새 노드가 루트 노드가 된다. 빈 트리가 아니라면, 루트 노드부터 시작하여 새 노드가 삽입될 위치를 찾을 때까지 재귀적으로 트리를 탐색한다. 새 노드는 항상 외부 노드의 왼쪽 또는 오른쪽 자식으로 삽입된다.
2. 삽입 후, 트리가 불균형 상태가 될 수 있다. 새롭게 삽입된 노드의 조상 노드들만 하위 트리가 변경되므로 불균형해질 수 있기 때문에, AVL 트리의 불변성을 유지하기 위해 각 조상 노드의 균형 인자를 검사("추적")해야 한다.[6]
3. 삽입 후 노드의 임시 균형 인자는 -2에서 +2 사이의 값을 갖게 된다. 각 노드의 임시 균형 인자가 -1에서 +1 사이에 있다면 균형 인자 업데이트만 필요하며 회전은 필요하지 않다. 그러나 임시 균형 인자가 ±2가 되면, 이 노드를 루트로 하는 서브트리는 불균형 상태가 되므로 회전이 필요하다.[9]
4. 회전은 트리 회전을 참고한다. 회전은 균형 계수가 2 이상 또는 -2 이하인 노드 중 가장 뿌리에서 먼 노드, 즉 가장 잎에 가까운 노드부터 수행한다.
- 대부분의 경우, "P"와 "P의 높은 쪽 부분 트리의 루트 노드"에 주목하여 한 번 회전을 수행하면, 이러한 노드와 그 자손 노드는 균형 조건을 만족하는 상태가 된다. 이 회전을 단일 회전 또는 1중 회전 등으로 부른다.
- 단일 회전으로 균형이 맞춰지지 않는 경우도 있다.
- P의 왼쪽 부분 트리가 더 높고, P의 왼쪽 자식 노드의 오른쪽 부분 트리가 더 높은 경우 (Left Right Case)
- P의 오른쪽 부분 트리가 더 높고, P의 오른쪽 자식 노드의 왼쪽 부분 트리가 더 높은 경우 (Right Left Case)
- 이 때는 복합 회전 또는 2중 회전 등을 수행하여 해결한다.
- 회전 전 P의 왼쪽 자식 노드를 L, L의 오른쪽 자식 노드를 LR이라고 하면, 먼저 L과 LR로 회전하고, 다음에 P와 새롭게 P의 왼쪽 자식 노드가 된 LR로 회전한다.
- 회전 전 P의 오른쪽 자식 노드를 R, R의 왼쪽 자식 노드를 RL이라고 하면, 먼저 R과 RL로 회전하고, 다음에 P와 새롭게 P의 오른쪽 자식 노드가 된 RL로 회전한다.
5. AVL 트리의 삽입 시 균형 조건 확인은 탐색해 온 경로상의 모든 노드가 균형 조건을 만족하는지 확인할 필요는 없으며, 탐색해 온 경로상의 어떤 노드를 회전시키거나, 탐색해 온 경로상에서 균형 계수가 0인 노드를 발견한 시점에서 처리를 종료할 수 있다.
- 삽입은 트리의 높이를 1 증가시키는 연산인 반해, 회전은 트리의 높이를 1 감소시키는 연산이므로, 이러한 연산에 의해 해당 부분 트리의 높이가 삽입 전과 같아지기 때문이다.
- 삽입으로 인해 균형 계수가 0이 된 노드가 있다는 것은, 삽입 전에 높이가 1 작았던 쪽의 부분 트리에 삽입했다는 것이므로, 해당 노드를 루트로 하는 부분 트리의 높이는 삽입 전후로 변하지 않아, 모든 노드가 균형 조건을 만족하고 있음을 알 수 있다.
6. 탐색해 온 경로상에서 균형 계수가 1 또는 -1인 노드를 발견해도 처리를 종료할 수 없다.
- 삽입으로 인해 균형 계수가 1 또는 -1이 된 노드가 있다는 것은, 삽입 전 해당 노드의 좌우 부분 트리의 높이는 같았지만, 삽입으로 인해 한쪽 부분 트리의 높이가 1 커졌다는 것이며, 해당 노드를 루트로 하는 부분 트리의 높이가 1 커졌으므로, 모든 노드가 균형 조건을 만족하고 있음을 보장할 수 없기 때문이다.
검색에 필요한 시간은 O(log n)이고, 루트로 돌아가는 길에 최대 O(log n) 추적 레벨(O(1) 평균)이 소요되므로, 이 연산은 O(log n) 시간 안에 완료될 수 있다.[9]
3. 4. 삭제 (Delete)
AVL 트리에서 노드 삭제는 일반적인 이진 탐색 트리의 삭제 연산과 유사하게 진행되지만, 높이 균형 성질을 유지하기 위해 삭제 후 트리의 재균형, 즉 회전(rotation)이 필요할 수 있다는 점이 다르다.삭제 과정은 다음과 같다:
1. 삭제할 노드 를 루트 노드부터 검색한다.
2. 가 단말 노드(자식이 없는 노드)가 아니라면, 왼쪽 부분 트리에서 가장 큰 값을 가진 노드나 오른쪽 부분 트리에서 가장 작은 값을 가진 노드를 찾아 와 위치를 바꾼다.
3. 가 단말 노드가 될 때까지 2번 과정을 반복하여 단말 노드 를 삭제한다.
삭제 후에는 트리의 균형이 깨질 수 있다. 이 경우, 삽입과 마찬가지로 의 부모 노드를 라고 하고, 회전을 통해 균형을 맞춘다. 이때, 삭제된 노드 또는 대체 노드의 자식 트리 높이가 1에서 0으로, 또는 2에서 1로 감소한다.[1]
삭제 후에는 AVL 트리의 불변성(모든 노드의 균형 인수가 -1, 0, 1 중 하나)을 유지하기 위해 각 조상 노드를 확인하는 "역추적" 과정이 필요하다.[1] 단일 삭제로 인해 AVL 서브트리의 높이는 최대 1만큼 감소할 수 있으므로, 노드의 임시 균형 인수는 -2에서 +2 사이의 값을 가질 수 있다.[1] 만약 균형 인수가 ±2가 되면, 해당 서브트리는 불균형 상태가 되므로 회전이 필요하다.[1]
삭제 시 역추적 과정에서 균형 인수가 ±1이 되면(원래 0이어야 함) 해당 서브트리의 높이는 변경되지 않았음을 의미하므로 역추적을 중단할 수 있다.[1] 균형 인수가 0이 되면(원래 ±1이어야 함) 서브트리의 높이가 1만큼 감소했음을 의미하므로 역추적을 계속해야 한다.[1]
삭제에 필요한 시간은 검색에 O(log ''n'') 시간이 걸리고, 루트 노드까지 돌아가는 경로에서 최대 O(log ''n'')번의 역추적(평균 O(1))이 필요하므로, 총 O(log ''n'') 시간이 걸린다.[1]
AVL 트리의 삭제 연산은 일반적인 이진 탐색 트리와 동일하게 삭제를 수행한 후, 균형 조건이 깨졌는지 확인하고 깨졌다면 회전을 통해 트리를 재구성한다.[2] 삽입과 마찬가지로, 삭제된 노드의 부모 노드부터 루트 노드 방향으로 경로를 조사하며, 균형 조건이 맞지 않는 노드가 있으면 단일 회전 또는 이중 회전을 수행한다.[2]
삭제할 노드가 자식 노드를 두 개 가진 경우, 삭제할 노드의 왼쪽 부분 트리에서 가장 큰 값을 가진 노드(또는 오른쪽 부분 트리에서 가장 작은 값을 가진 노드)를 찾아 삭제할 노드와 교체하는 과정이 필요하며, 이때 탐색한 경로도 기억해야 한다.[2] 노드 삭제는 교체 후에 이루어지므로, 균형 조건 확인도 교체된 노드의 부모 노드부터 시작해야 한다.[2]
삭제 시 균형 조건 확인 과정에서 균형 계수가 1 또는 -1인 노드를 발견하면, 해당 노드를 루트로 하는 부분 트리의 높이는 삭제 전후로 변하지 않으므로, 모든 노드가 균형 조건을 만족하고 있음이 보장되어 처리를 종료할 수 있다.[2] 그러나 균형 계수가 0인 노드를 발견하거나 회전을 수행한 경우에는, 해당 부분 트리의 높이가 변경되었을 수 있으므로, 추가적인 확인이 필요할 수 있다.[2]
3. 5. 회전 (Rotation)
AVL 트리에서 회전은 트리의 균형을 유지하기 위한 중요한 연산이다. 삽입이나 삭제로 인해 트리의 균형이 깨질 수 있는데, 이때 회전을 통해 균형을 회복한다. 회전에는 단일 회전과 이중 회전 두 가지가 있으며, 이들은 모두 O(1) 시간 복잡도를 가진다.[11]AVL 트리에서 노드 삽입 및 삭제 시, 일반적인 이진 탐색 트리와 동일한 과정을 거치지만, 높이 균형 성질(height balance property)을 만족하지 않게 될 수 있다. 이때 회전을 통해 트리를 재구성하여 높이 균형 성질을 유지한다.[6] [12]
회전의 기준이 되는 세 노드 x, y, z는 다음과 같이 정의된다.
- z: 삽입/삭제된 노드로부터 루트 노드로 가는 경로 상에서 가장 먼저 나타나는 불균형 노드
- y: z의 자식 중 더 높은 높이를 갖는 노드
- x: y의 자식 중 더 높은 높이를 갖는 노드
회전은 이 세 노드와 그 서브트리들을 재배치하여 균형을 맞추는 작업이다. 구체적인 회전 방법은 단일 회전과 이중 회전에서 설명한다.
3. 5. 1. 단일 회전 (Single Rotation)
''rotate_Left''(''X'',''Z'')]];단순 왼쪽 회전의 코드 조각
입력 | X = 왼쪽으로 회전될 서브트리의 루트 |
---|---|
Z = X의 오른쪽 자식, Z는 오른쪽으로 무거움 | |
높이 == X | |
결과 | 재균형된 서브트리의 새로운 루트 |
```c
node *rotate_Left(node *X, node *Z) {
// Z는 형제보다 2만큼 높음
t23 = left_child(Z); // Z의 내부 자식
right_child(X) = t23;
if (t23 != null)
parent(t23) = X;
left_child(Z) = X;
parent(X) = Z;
// 첫 번째 경우, BF(Z) == 0,
// 삭제 시에만 발생하며, 삽입 시에는 발생하지 않음:
if (BF(Z) == 0) { // t23이 t4와 높이가 같았음
BF(X) = +1; // t23이 이제 더 높음
BF(Z) = –1; // t4가 이제 X보다 낮음
} else { // 두 번째 경우는 삽입 또는 삭제 시 발생:
BF(X) = 0;
BF(Z) = 0;
}
return Z; // 회전된 서브트리의 새로운 루트 반환
}
```
일반적인 이진 탐색 트리에서의 삽입은 "왼쪽 자식의 값 ≤ 부모의 값 ≤ 오른쪽 자식의 값"을 만족하는 가지의 말단을 탐색하여, 거기에 새로 생성한 노드를 연결하지만, AVL 트리에서는 균형 조건을 만족하는지 조사하고, 만족하지 않는 경우에는 회전을 수행한다.
삽입 후, "삽입한 노드의 부모 노드"에서 "루트 노드"를 향해 순서대로 조사해 나갈때, 균형 조건을 만족하지 않는 노드(P라고 한다)가 있는 경우, "P"와 "P의 높은 쪽 부분 트리의 루트 노드"에 주목하여 한 번 회전을 수행하면, 이러한 노드와 그 자손 노드는 균형 조건을 만족하는 상태가 된다. 이 회전을 단일 회전 또는 1중 회전 등으로 부른다.
3. 5. 2. 이중 회전 (Double Rotation)
트리의 재구성 작업은 회전(Rotation)이라고 불린다. 이중 회전은 불균형 노드와 그 자식 노드의 방향이 다른 경우(LR, RL)에 수행된다.가 이진 탐색 트리의 노드이고 가 부모, 가 할아버지 노드일 때 다음과 같이 재구성한다.
# , , 를 왼쪽-오른쪽 순서 (inorder)로 나열 한 순서대로 , , 라고 하고, , , 의 4개의 부분 트리들을 왼쪽-오른쪽 순서 (inorder)로 나열한 것을 , , , 라고 한다.
# 가 root인 부분 트리를 를 root로 하는 새로운 부분 트리로 바꾼다.
# 가 의 왼쪽 자식이 되고 , 은 각각 의 왼쪽, 오른쪽 자식이 된다.
# 가 의 오른쪽 자식이 되고, , 는 각각 의 왼쪽, 오른쪽 자식이 된다.
일 때 를 와 회전시키고 다시 와 회전시키는 것처럼 보인다. 이 작업을 double rotation이라고 한다.
일반적인 이진 탐색 트리에서의 삽입과 달리 AVL 트리는 삽입 후에 균형이 맞지 않을 때 회전을 한다. 단일 회전으로 균형이 맞춰지지 않는 경우는 다음과 같다.
- P의 왼쪽 부분 트리가 더 높고, P의 왼쪽 자식 노드의 오른쪽 부분 트리가 더 높은 경우 (그림의 Left Right Case)
- P의 오른쪽 부분 트리가 더 높고, P의 오른쪽 자식 노드의 왼쪽 부분 트리가 더 높은 경우 (그림의 Right Left Case)
이 경우에는 각각 다음과 같이 두 번 회전을 수행함으로써 해결할 수 있다. 이를 복합 회전 또는 2중 회전 등으로 부른다.
- 회전 전 P의 왼쪽 자식 노드를 L, L의 오른쪽 자식 노드를 LR이라고 하면, 먼저 L과 LR로 회전하고, 다음에 P와 새롭게 P의 왼쪽 자식 노드가 된 LR로 회전한다.
- 회전 전 P의 오른쪽 자식 노드를 R, R의 왼쪽 자식 노드를 RL이라고 하면, 먼저 R과 RL로 회전하고, 다음에 P와 새롭게 P의 오른쪽 자식 노드가 된 RL로 회전한다.
3. 6. 집합 연산 (Set Operations)
AVL 트리는 합집합, 교집합, 차집합과 같은 집합 연산을 지원한다.[13] 이러한 연산은 분할(Split)과 결합(Join)이라는 두 가지 헬퍼 연산을 기반으로 효율적으로 구현될 수 있다.- 결합(Join) 연산: 두 개의 AVL 트리 과 및 키 가 주어졌을 때, 과 의 모든 요소와 를 포함하는 하나의 트리를 반환한다. 단, 는 의 모든 키보다 크고 의 모든 키보다 작아야 한다. 이 연산의 비용은 두 입력 트리의 높이 차이에 비례한다.
- 분할(Split) 연산: AVL 트리를 특정 키 를 기준으로 작은 두 개의 트리로 나눈다. 하나는 보다 작은 키를, 다른 하나는 보다 큰 키를 갖는 트리이다. 이 연산의 비용은 이며, 이는 트리의 높이에 해당한다.
이러한 헬퍼 연산들을 사용하여 두 AVL 트리의 합집합, 교집합, 차집합을 구할 수 있다. 예를 들어, 두 AVL 트리 과 의 합집합은 다음과 같이 계산할 수 있다.
1. 를 의 루트 키를 기준으로 분할하여 두 개의 트리 와 를 얻는다.
2. 의 왼쪽 서브트리와 의 합집합, 의 오른쪽 서브트리와 의 합집합을 재귀적으로 계산한다.
3. 2단계에서 얻은 두 합집합과 의 루트를 결합(Join)하여 최종 합집합 트리를 생성한다.
교집합과 차집합 연산도 유사한 방식으로 구현할 수 있다. 이러한 집합 연산들은 재귀 호출이 서로 독립적이므로 병렬 처리가 가능하다.[13]
합집합, 교집합, 차집합의 복잡도는 크기가 및 인 AVL 트리에 대해 이다. 또한, 이러한 연산은 병렬로 병렬 깊이 로 실행될 수 있다.[13]
4. 다른 자료 구조와의 비교
AVL 트리와 레드-블랙 트리는 모두 자체 균형 이진 탐색 트리이며, 수학적으로 관련이 있다.[14] 모든 AVL 트리는 레드-블랙 트리로 칠할 수 있지만, AVL 균형을 이루지 않는 레드-블랙 트리도 존재한다.[14] AVL 트리는 레드-블랙 트리에 비해 더 엄격하게 균형을 유지하므로, 탐색 성능은 AVL 트리가 더 좋지만 삽입 및 삭제 성능은 레드-블랙 트리가 더 좋을 수 있다.
AVL 트리와 레드-블랙 트리는 회전을 통해 트리의 균형을 유지한다. 최악의 경우, 회전 없이도 AVL 또는 레드-블랙 트리 삽입 또는 삭제는 AVL 균형 인자(또는 레드-블랙 트리의 색상)에 대한 검사 및/또는 업데이트가 필요하다. 레드-블랙 트리의 삽입 및 삭제와 AVL 트리의 삽입은 0개에서 3개의 꼬리 재귀 회전을 필요로 하며 상각된 시간에 실행되므로,[15] [16] 평균적으로도 일정하다. 최악의 경우 회전이 필요한 AVL 삭제도 평균적으로는 이다.
레드-블랙 트리는 각 노드에 1비트의 정보(색상)를 저장해야 하는 반면, AVL 트리는 대부분 균형 인자에 대해 2비트를 사용하지만, 자식에 저장될 때는 «형제보다 낮음»의 의미를 가진 1비트면 충분하다.
크기가 인 트리의 경우, AVL 트리의 높이는 최대 ${\displaystyle h\leqq \;c\log _{2}(n+d)+b< \;c\log _{2}(n+2)+b}$이다. 여기서 ${\displaystyle \varphi :={\tfrac {1+{\sqrt {5}}}{2}}\approx 1.618}$는 황금비, ${\displaystyle c:={\tfrac {1}{\log _{2}\varphi }}\approx 1.440}$, ${\displaystyle b:={\tfrac {c}{2}}\log _{2}5-2\approx \;-0.328}$, ${\displaystyle d:=1+{\tfrac {1}{\varphi ^{4}{\sqrt {5}}}}\approx 1.065}$이다. 반면 레드-블랙 트리의 높이는 최대 ${\displaystyle h\leqq \;2\log _{2}(n+1)}$이다.[17]
AVL 트리는 레드-블랙 트리보다 더 엄격하게 균형을 이루며, 최대 높이의 점근 관계는 AVL/RB ≈0.720이다. 삽입 및 삭제의 경우, Ben Pfaff는 79개의 측정에서 AVL/RB 관계가 0.677과 1.077 사이이며 중앙값 ≈0.947 및 기하 평균 ≈0.910임을 보여준다.[4]
5. 응용
AVL 트리는 일반적인 이진 탐색 트리와 달리 데이터 입력 순서에 관계없이 항상 균형 잡힌 트리를 유지하여 탐색 효율을 높인다. 일반적인 이진 탐색 트리는 데이터가 정렬된 상태로 입력되면 트리가 선형 리스트처럼 구성되어 탐색 계산량이 최악의 경우 이 된다. 반면 AVL 트리는 "어떤 노드의 좌우 서브트리의 높이 차도 1 이하"라는 평형 조건을 항상 만족시켜 탐색 계산량이 항상 이다. 이러한 특성으로 AVL 트리는 데이터베이스 시스템, 운영체제, 컴파일러 등 다양한 분야에서 효율적인 자료 구조로 활용되며, 특히 탐색 연산이 빈번한 환경에서 뛰어난 성능을 제공한다.
참조
[1]
웹사이트
AVL Trees
http://pages.cs.wisc[...]
[2]
논문
An algorithm for the organization of information
https://zhjwpku.com/[...]
[3]
서적
Algorithms
Addison-Wesley
[4]
웹사이트
Performance Analysis of BSTs in System Software
http://www.stanford.[...]
Stanford University
2004-06
[5]
웹사이트
AVL trees are not weight-balanced? (meaning: AVL trees are not μ-balanced?)
https://cs.stackexch[...]
[6]
서적
Sorting and searching
Addison-Wesley
[7]
문서
However, the balance information can be kept in the child nodes as one bit indicating whether the parent is higher by 1 or by 2; thereby higher by 2 cannot occur for both children. This way the AVL tree is a [[WAVL tree|"rank balanced" tree]], as coined by [[#Haeupler|Haeupler, Sen and Tarjan]].
[8]
서적
Mastering data structures through 'C' language
University Science Press, an imprint of Laxmi Publications Pvt. Ltd.
[9]
서적
Advanced data structures
Cambridge University Press
2008
[10]
서적
Schaum's outline of theory and problems of data structures with Java
https://archive.org/[...]
McGraw-Hill
2000
[11]
서적
Data structures and algorithm analysis in C++
Pearson Addison-Wesley
2006
[12]
서적
An Introduction to Binary Search Trees and Balanced Trees
Free Software Foundation, Inc.
2004
[13]
간행물
Symposium on Parallel Algorithms and Architectures
ACM
[14]
웹사이트
AVL tree
https://xlinux.nist.[...]
National Institute of Standards and Technology
2016-07-02
[15]
서적
Algorithms and Data Structures
http://link.springer[...]
Springer Berlin Heidelberg
2008
[16]
서적
Handbook of Data Structures and Applications
https://www.taylorfr[...]
Chapman and Hall/CRC
2017-12-15
[17]
문서
Red–black tree#Proof of bounds
[18]
웹인용
AVL Trees
http://pages.cs.wisc[...]
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com